﻿using PCControl服务;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Pipes;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace PCControlService
{
    public class TisnControl
    {
        public struct COPYDATASTRUCT
        {
            public IntPtr dwData;
            public int cbData;
            [MarshalAs(UnmanagedType.LPStr)]
            public string lpData;
        }
        //Win32 API函数

        [DllImport("User32.dll", EntryPoint = "SendMessage")]
        private static extern int SendMessage(int hWnd, int Msg, int wParam, ref COPYDATASTRUCT lParam);

        [DllImport("User32.dll", EntryPoint = "FindWindow")]
        private static extern int FindWindow(string lpClassName, string lpWindowName);

        const int WM_PCCONTROL = 5317520;

        [DllImport("user32.dll", EntryPoint = "keybd_event", SetLastError = true)]
        public static extern void keybd_event(Keys bVk, byte bScan, uint dwFlags, uint dwExtraInfo);
        [DllImport("user32.dll")]
        public static extern byte MapVirtualKey(Keys Ucode, uint uMapType);
        public const int KEYEVENTF_EXTENDEDKEY = 1;

        public const int KEYEVENTF_KEYUP = 2;
        public const int KEYEVENTF_UNICODE = 4;
        public const int KEYEVENTF_SCANCODE = 8;
        public static void SendKey(Keys key, bool ctrl = false, bool shift = false, bool alt = false, bool win = false)
        {
            if (ctrl)
            {
                keybd_event(Keys.Control, 0, 0, 0);
            }
            if (shift)
            {
                keybd_event(Keys.Shift, 0, 0, 0);
            }
            if (alt)
            {
                keybd_event(Keys.Alt, 0, 0, 0);
            }
            if (win)
            {
                keybd_event(Keys.LWin, 0, 0, 0);
            }
            keybd_event(key, MapVirtualKey(key, 0), KEYEVENTF_EXTENDEDKEY, 0);
            keybd_event(key, MapVirtualKey(key, 0), KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
            if (ctrl)
            {
                keybd_event(Keys.Control, 0, KEYEVENTF_KEYUP, 0);
            }
            if (shift)
            {
                keybd_event(Keys.Shift, 0, KEYEVENTF_KEYUP, 0);
            }
            if (alt)
            {
                keybd_event(Keys.Alt, 0, KEYEVENTF_KEYUP, 0);
            }
            if (win)
            {
                keybd_event(Keys.LWin, 0, KEYEVENTF_KEYUP, 0);
            }
        }

        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        internal struct TokPriv1Luid
        {
            public int Count;
            public long Luid;
            public int Attr;
        }

        //C#关机代码    
        [DllImport("kernel32.dll", ExactSpelling = true)]
        internal static extern IntPtr GetCurrentProcess();

        [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
        internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok);

        [DllImport("advapi32.dll", SetLastError = true)]
        internal static extern bool LookupPrivilegeValue(string host, string name, ref long pluid);

        [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
        internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall,
        ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);

        [DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
        internal static extern bool ExitWindowsEx(int flg, int rea);

        internal const int SE_PRIVILEGE_ENABLED = 0x00000002;
        internal const int TOKEN_QUERY = 0x00000008;
        internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
        internal const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege";
        internal const int EWX_LOGOFF = 0x00000000;
        internal const int EWX_SHUTDOWN = 0x00000001;
        internal const int EWX_REBOOT = 0x00000002;
        internal const int EWX_FORCE = 0x00000004;
        internal const int EWX_POWEROFF = 0x00000008;
        internal const int EWX_FORCEIFHUNG = 0x00000010;
        //C#关机代码    
        public static void DoExitWin(int flg = EWX_SHUTDOWN)
        {
            bool ok;
            TokPriv1Luid tp;
            IntPtr hproc = GetCurrentProcess();
            IntPtr htok = IntPtr.Zero;
            ok = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
            tp.Count = 1;
            tp.Luid = 0;
            tp.Attr = SE_PRIVILEGE_ENABLED;
            ok = LookupPrivilegeValue(null, SE_SHUTDOWN_NAME, ref tp.Luid);
            ok = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
            ok = ExitWindowsEx(flg, 0);
        }

        public static void Reboot()
        {
            DoExitWin(EWX_REBOOT);
        }

        public static void TryStartCMD()
        {
            if (System.Diagnostics.Process.GetProcessesByName("PCControlCommand.exe").Length == 0)
            {
                var p = $"{Application.StartupPath}\\PCControlCommand.exe";
                WinAPI_Interop.CreateProcess(p);
            }
        }

    }
}
